#!/usr/bin/python3
import threading
import time
from tkinter import *
from tkinter import filedialog
from tkinter.ttk import Progressbar, Combobox
from const.byte_order_enum import ByteOrder
from const.charset_enum import Charset
from const.dot_matrix_style import DotMatrixStyle
from const.font_enum import Font
from const.font_mode_enum import FontMode
from draw.Draw import Draw
from generator.gen_default import GenDefault
from generator.gen_gb2312 import GenGB2312
from generator.gen_gbk import GenGBK
from generator.gen_unicode import GenUnicode
from dto.param import Param, CANVAS_SIZE

# 界面的默认字体样式
FONT = ('Microsoft YaHei', 12)


class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master, bg='#87CEEB')
        self.thread_draw_point = None
        self.canvas = None
        self.displayRegion = None
        self.fontComboboxLabel = None
        self.fontCombobox = None
        self.charsetCombobox = None
        self.charsetComboboxLabel = None
        self.charsetRegionLabel = None
        self.charsetRegionStartLabel = None
        self.charsetRegionStart = None
        self.charsetRegionEnd = None
        self.charsetRegionEndLabel = None
        self.fontModeComboboxLabel = None
        self.fontModeCombobox = None
        self.dotMatrixSizeLabel = None
        self.dotMatrixSize = None
        self.byte_order_var = None
        self.byteorderLabel = None
        self.byteorder1 = None
        self.byteorder2 = None
        self.dot_matrix_var = None
        self.dotMatrixStyleLabel = None
        self.dotMatrixStyle1 = None
        self.dotMatrixStyle2 = None
        self.saveLabel = None
        self.locationText = None
        self.browseButton = None
        self.progressBarLabel = None
        self.progressBar = None
        self.progressBarText = None
        self.generateButton = None

        self.param = Param(self)
        self.param.callback = self.update_progress

        self.draw = Draw()

        self.pack(fill=BOTH, expand=True)
        self.create_widgets()

    def create_widgets(self):
        # 选择字体：宋体、楷体等
        self.fontComboboxLabel = Label(self, text="字体：", font=FONT, anchor='e', justify=RIGHT, width=12)
        self.fontCombobox = Combobox(self, state='readonly', font=FONT, values=Font.values())
        self.fontCombobox.current(0)

        # 字符集：GBK、Unicode
        self.charsetComboboxLabel = Label(self, text="字符集：", font=FONT, anchor='e', justify=RIGHT, width=12)
        self.charsetCombobox = Combobox(self, state='readonly', font=FONT, values=Charset.values())
        self.charsetCombobox.bind("<<ComboboxSelected>>", self.on_charset_select)
        self.charsetCombobox.current(0)

        # 范围
        self.charsetRegionLabel = Label(self, text="字符集范围：", font=FONT, anchor='e', justify=RIGHT, width=12)
        self.charsetRegionStartLabel = Label(self, text="开始字符：", font=FONT, anchor='e', width=20)
        self.charsetRegionStart = Entry(self, bd=2, font=FONT)
        self.charsetRegionEndLabel = Label(self, text="结束字符：", font=FONT, anchor='e', width=20)
        self.charsetRegionEnd = Entry(self, bd=2, font=FONT)
        charset_region = Charset.get_charset_region(self.charsetCombobox.get())
        self.charsetRegionStart.insert(0, charset_region[0])
        self.charsetRegionEnd.insert(0, charset_region[1])

        # 点阵宽高：推荐 12、16、24
        self.dotMatrixSizeLabel = Label(self, text="点阵宽高：", font=FONT, anchor='e', justify=RIGHT, width=12)
        self.dotMatrixSize = Entry(self, bd=2, font=FONT, width=22)
        self.dotMatrixSize.insert(0, '16')
        self.dotMatrixSize.bind("<Return>", self.on_draw)

        # 生成模式：纵向先上下后左右、纵向先左右后上下
        self.fontModeComboboxLabel = Label(self, text="生成模式：", font=FONT, anchor='e', justify=RIGHT, width=12)
        self.fontModeCombobox = Combobox(self, state='readonly', font=FONT, values=FontMode.values())
        self.fontModeCombobox.bind("<<ComboboxSelected>>", self.on_draw)
        self.fontModeCombobox.current(0)

        # 字节序
        self.byte_order_var = StringVar()
        self.byte_order_var.set(value=ByteOrder.names()[1])
        self.byteorderLabel = Label(self, text="字节序：", font=FONT, anchor='e', justify=RIGHT, width=12)
        self.byteorder1 = Radiobutton(self, text=ByteOrder.values()[0], variable=self.byte_order_var, font=FONT,
                                      anchor='w', width=17, value=ByteOrder.names()[0])
        self.byteorder2 = Radiobutton(self, text=ByteOrder.values()[1], variable=self.byte_order_var, font=FONT,
                                      anchor='w', width=17, value=ByteOrder.names()[1])
        self.byte_order_var.trace('w', self.on_draw)

        # 点阵格式
        self.dot_matrix_var = StringVar()
        self.dot_matrix_var.set(DotMatrixStyle.names()[0])
        self.dotMatrixStyleLabel = Label(self, text="点阵格式：", font=FONT, anchor='e', justify=RIGHT, width=12)
        self.dotMatrixStyle1 = Radiobutton(self, variable=self.dot_matrix_var, font=FONT, width=17, anchor='w',
                                           text=DotMatrixStyle.values()[0], value=DotMatrixStyle.names()[0])
        self.dotMatrixStyle2 = Radiobutton(self, variable=self.dot_matrix_var, font=FONT, width=17, anchor='w',
                                           text=DotMatrixStyle.values()[1], value=DotMatrixStyle.names()[1])
        self.dot_matrix_var.trace('w', self.on_draw)

        # 保存位置
        self.saveLabel = Label(self, text="保存位置：", font=FONT, anchor='e', justify=RIGHT, width=12)
        self.locationText = Entry(self, width=60, bd=2, font=FONT)
        self.locationText.insert(0, "D:/")
        self.browseButton = Button(self, text='...', font=FONT, anchor='center', width=6, command=self.on_ask_location)

        # 进度条
        self.progressBarLabel = Label(self, text="生成进度：", font=FONT, anchor='e', justify=RIGHT, width=12)
        self.progressBar = Progressbar(self, orient='horizontal', length=546, mode="determinate")
        self.progressBarText = Label(self, text="0.00%", font=FONT, width=6)

        # 生成按键
        self.generateButton = Button(self, text='生成', font=FONT, width=10, command=self.on_generate)

        self.displayRegion = Frame(self, padx=5, pady=5, bg='#87CEEB')
        self.canvas = Canvas(self.displayRegion, width=CANVAS_SIZE, height=CANVAS_SIZE, bg='black')
        self.canvas.pack()

        self.do_layout()
        self.on_draw()

    def do_layout(self):
        self.charsetComboboxLabel   .grid(row=0, column=0, padx=5, pady=5)
        self.charsetCombobox        .grid(row=0, column=1, padx=5, pady=5)
        self.charsetRegionLabel     .grid(row=1, column=0, padx=5, pady=5)
        self.charsetRegionStartLabel.grid(row=1, column=1, padx=5, pady=5)
        self.charsetRegionStart     .grid(row=1, column=2, padx=5, pady=5)
        self.charsetRegionEndLabel  .grid(row=1, column=3, padx=5, pady=5)
        self.charsetRegionEnd       .grid(row=1, column=4, padx=5, pady=5)
        self.fontComboboxLabel      .grid(row=2, column=0, padx=5, pady=5)
        self.fontCombobox           .grid(row=2, column=1, padx=5, pady=5)
        self.dotMatrixSizeLabel     .grid(row=3, column=0, padx=5, pady=5)
        self.dotMatrixSize          .grid(row=3, column=1, padx=5, pady=5)
        self.fontModeComboboxLabel  .grid(row=4, column=0, padx=5, pady=5)
        self.fontModeCombobox       .grid(row=4, column=1, padx=5, pady=5)
        self.byteorderLabel         .grid(row=5, column=0, padx=5, pady=5)
        self.byteorder1             .grid(row=5, column=1, padx=5, pady=5)
        self.byteorder2             .grid(row=5, column=2, padx=5, pady=5)
        self.dotMatrixStyleLabel    .grid(row=6, column=0, padx=5, pady=5)
        self.dotMatrixStyle1        .grid(row=6, column=1, padx=5, pady=5)
        self.dotMatrixStyle2        .grid(row=6, column=2, padx=5, pady=5)
        self.displayRegion          .grid(row=2, column=3, padx=5, pady=5, columnspan=2, rowspan=5, sticky=NSEW)
        self.saveLabel              .grid(row=7, column=0, padx=5, pady=5)
        self.locationText           .grid(row=7, column=1, padx=5, pady=5, columnspan=3)
        self.browseButton           .grid(row=7, column=4, padx=5, pady=5)
        self.progressBarLabel       .grid(row=8, column=0, padx=5, pady=5)
        self.progressBar            .grid(row=8, column=1, padx=5, pady=5, columnspan=3)
        self.progressBarText        .grid(row=8, column=4, padx=5, pady=5, columnspan=3)
        self.generateButton         .grid(row=9, column=1, padx=5, pady=5, columnspan=3)

    def on_charset_select(self, event):
        self.param.charset = Charset.get_name(self.charsetCombobox.get())

        self.charsetRegionStart.delete(0, END)
        self.charsetRegionEnd.delete(0, END)
        region = Charset.get_charset_region(self.charsetCombobox.get())
        self.charsetRegionStart.insert(0, region[0])
        self.charsetRegionEnd.insert(0, region[1])

    def on_font_mode_select(self, event):
        self.on_draw()

    def on_ask_location(self):
        directory = filedialog.askdirectory(title="选择目录", initialdir="/")
        if directory:
            # 如果用户选择了目录，将其显示在文本框中
            self.locationText.delete(0, END)
            self.locationText.insert(0, directory)
            self.param.location = directory

    def on_draw(self, *args):
        self.draw.stop()
        time.sleep(0.1)
        self.draw.start()

        mode = FontMode.get_name(self.fontModeCombobox.get())
        style = self.dot_matrix_var.get()
        if style == DotMatrixStyle.POSITIVE.name.lower():
            color = '#1890FF'
            bg = '#000000'
        else:
            color = '#000000'
            bg = '#1890FF'
        font_size = int(self.dotMatrixSize.get())
        byte_order = self.byte_order_var.get()
        self.thread_draw_point = threading.Thread(target=self.draw.draw,
                                                  args=(self.canvas, mode, font_size, byte_order, color, bg))
        self.thread_draw_point.start()

    def update_progress(self, p: int = 0, percent: str = "0.00"):
        self.progressBar['value'] = p
        self.progressBarText['text'] = str(percent)
        self.update_idletasks()

    def on_generate(self):
        self.param.font = Font.get_name(self.fontCombobox.get())
        self.param.charset = Charset.get_name(self.charsetCombobox.get())
        self.param.charsetStart = self.charsetRegionStart.get()
        self.param.charsetEnd = self.charsetRegionEnd.get()
        self.param.fontHeight = self.dotMatrixSize.get()
        self.param.fontWidth = self.dotMatrixSize.get()
        self.param.dotMatrixMode = FontMode.get_name(self.fontModeCombobox.get())
        self.param.byteOrder = self.byte_order_var.get()
        self.param.dotMatrixStyle = self.dot_matrix_var.get()
        self.param.location = self.locationText.get()
        self.param.callback = self.update_progress

        if self.param.charset == Charset.GB2312.name.lower():
            gen = GenGB2312(self.param)
        elif self.param.charset == Charset.GBK.name.lower():
            gen = GenGBK(self.param)
        elif self.param.charset == Charset.UNICODE.name.lower():
            gen = GenUnicode(self.param)
        else:
            gen = GenDefault(self.param)
        # gen.do_gen()
        t1 = threading.Thread(target=gen.do_gen(), args=(self.param,))
        t1.start()


if __name__ == '__main__':
    app = Application()
    # 设置窗口标题:
    app.master.title('汉字字库点阵生成器 v1.0')
    # 窗口图标
    # app.master.iconbitmap('imgs/1.ico')
    app.master.resizable(False, False)
    # 主消息循环:
    app.mainloop()
